package com.aboo.frame.util.okhttp;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Request.Builder;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 
 * 项目名称：  studydemo
 * 类名称：  OkhttpUtil   
 * 描述：  http请求基础工具类
 * @author  娄安   
 * 创建时间：  2020年1月14日 下午7:55:41 
 * 修改人：娄安    修改日期： 2020年1月14日
 * 修改备注：
 *
 */
@Slf4j
public class OkhttpUtil {

	/**
	 * 连接超时时间
	 */
	private static final long DEFAULT_CONNECT_TIME = 10000;
	/**
	 * 读取超时时间
	 */
	private static final long DEFAULT_READ_TIME = 30000;
	/**
	 * 写入超时时间
	 */
	private static final long DEFAULT_WRITE_TIME = 30000;

	/**
	 * 
	 * 方法名：  doPost 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:14:10
	 * @param url
	 * @param param
	 * @return
	 *
	 */
	public static String doPost(String url, Map<String, String> param) {
		return doPost(url, param, null);
	}

	/**
	 * 
	 * 方法名：  doGet 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:14:06
	 * @param url
	 * @param param
	 * @return
	 *
	 */
	public static String doGet(String url, Map<String, String> param) {
		return doGet(url, param, null);
	}

	/**
	 * 
	 * 方法名：  doPostJson 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:14:03
	 * @param url
	 * @param json
	 * @return
	 *
	 */
	public static String doPostJson(String url, String json) {
		return doPostJson(url, json, null);
	}

	/**
	 * 
	 * 方法名：  doPost 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:59
	 * @param url
	 * @param param
	 * @param header
	 * @return
	 *
	 */
	public static String doPost(String url, Map<String, String> param, Map<String, String> header) {
		return doPost(url, param, header, new TimeSet());
	}

	/**
	 * 
	 * 方法名：  doGet 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:54
	 * @param url
	 * @param param
	 * @param header
	 * @return
	 *
	 */
	public static String doGet(String url, Map<String, String> param, Map<String, String> header) {
		return doGet(url, param, header, new TimeSet());
	}

	/**
	 * 
	 * 方法名：  doPostJson 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:50
	 * @param url
	 * @param json
	 * @param header
	 * @return
	 *
	 */
	public static String doPostJson(String url, String json, Map<String, String> header) {
		return doPostJson(url, json, header, new TimeSet());
	}

	/**
	 * 
	 * 方法名：  doPost 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:47
	 * @param url
	 * @param param
	 * @param header
	 * @param times
	 * @return
	 *
	 */
	public static String doPost(String url, Map<String, String> param, Map<String, String> header, TimeSet times) {
		Response response = doResponse("POST", url, param, header, times);

		String body = "";
		try {
			if (response != null) {
				body = response.body().string();
			}
		} catch (Exception e) {
			log.error("请求失败，URL：{}", url, e);
		}

		return body;
	}

	/**
	 * 
	 * 方法名：  doGet 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:43
	 * @param url
	 * @param param
	 * @param header
	 * @param times
	 * @return
	 *
	 */
	public static String doGet(String url, Map<String, String> param, Map<String, String> header, TimeSet times) {
		Response response = doResponse("GET", url, param, header, times);

		String body = "";
		try {
			if (response != null) {
				body = response.body().string();
			}
		} catch (Exception e) {
			log.error("请求失败，URL：{}", url, e);
		}

		return body;
	}

	/**
	 * 
	 * 方法名：  doPostJson 
	 * 描述：  
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:38
	 * @param url
	 * @param json
	 * @param header
	 * @param times
	 * @return
	 *
	 */
	public static String doPostJson(String url, String json, Map<String, String> header, TimeSet times) {
		Map<String, String> param = new HashMap<>();
		param.put("json", json);
		Response response = doResponse("POST_JSON", url, param, header, times);

		String body = "";
		try {
			if (response != null) {
				body = response.body().string();
			}
		} catch (Exception e) {
			log.error("请求失败，URL：{}", url, e);
		}

		return body;
	}

	/**
	 * 
	 * 方法名：  doResponse 
	 * 描述：  核心请求方法
	 * @author  娄安   
	 * 创建时间：2020年1月14日 下午8:13:29
	 * @param type
	 * @param url
	 * @param param
	 * @param header
	 * @param times
	 * @return
	 *
	 */
	public static Response doResponse(String type, String url, Map<String, String> param, Map<String, String> header,
			TimeSet times) {
		Response response = null;
		Request request = null;
		OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
		
		// 设置超时时间
		if (times.getConnect() > 0) {
			clientBuilder.connectTimeout(times.getConnect(), TimeUnit.MILLISECONDS);
		} else {
			clientBuilder.connectTimeout(DEFAULT_CONNECT_TIME, TimeUnit.MILLISECONDS);
		}
		if (times.getRead() > 0) {
			clientBuilder.readTimeout(times.getRead(), TimeUnit.MILLISECONDS);
		} else {
			clientBuilder.readTimeout(DEFAULT_READ_TIME, TimeUnit.MILLISECONDS);
		}
		if (times.getWrite() > 0) {
			clientBuilder.writeTimeout(times.getWrite(), TimeUnit.MILLISECONDS);
		} else {
			clientBuilder.writeTimeout(DEFAULT_WRITE_TIME, TimeUnit.MILLISECONDS);
		}

		// 添加请求头
		if (MapUtils.isNotEmpty(header)) {
			clientBuilder.addInterceptor(new Interceptor() {
				@Override
				public Response intercept(Chain chain) throws IOException {
					Builder headerBuilder = chain.request().newBuilder();
					Set<Entry<String, String>> entrySet = header.entrySet();
					Iterator<Entry<String, String>> iter = entrySet.iterator();
					while (iter.hasNext()) {
						Entry<String, String> entry = iter.next();
						headerBuilder.addHeader(entry.getKey(), StringUtils.defaultString(entry.getValue()));
					}

					Request request = headerBuilder.build();
					return chain.proceed(request);
				}
			});
		}

		OkHttpClient okHttpClient = clientBuilder.build();
		Request.Builder requestBuilder = new Request.Builder();
		if ("POST".equals(type)) {
			FormBody.Builder bodyBuilder = new FormBody.Builder();
			if (MapUtils.isNotEmpty(param)) {
				Set<Entry<String, String>> entrySet = param.entrySet();
				Iterator<Entry<String, String>> iter = entrySet.iterator();
				while (iter.hasNext()) {
					Entry<String, String> entry = iter.next();
					bodyBuilder.add(entry.getKey(), StringUtils.defaultString(entry.getValue()));
				}
			}
			RequestBody body = bodyBuilder.build();
			requestBuilder.url(url).post(body);
		} else if ("GET".equals(type)) {
			if (MapUtils.isNotEmpty(param)) {
				StringBuilder sb = new StringBuilder();
				Set<Entry<String, String>> entrySet = param.entrySet();
				Iterator<Entry<String, String>> iter = entrySet.iterator();
				while (iter.hasNext()) {
					Entry<String, String> entry = iter.next();
					sb.append(entry.getKey()).append("=").append(StringUtils.defaultString(entry.getValue()))
							.append("&");
				}
				url += ("?" + sb.substring(0, sb.length() - 1));
			}
			requestBuilder.url(url).get();
		} else if ("POST_JSON".equals(type)) {
			MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
			String json = "{}";
			if (MapUtils.isNotEmpty(param)) {
				json = param.get("json");
			}
			RequestBody body = RequestBody.create(mediaType, json);
			requestBuilder.url(url).post(body);
		}

		request = requestBuilder.build();
		Call call = okHttpClient.newCall(request);
		try {
			response = call.execute();
		} catch (IOException e) {
			log.error("请求失败，URL：{}", url, e);
			response = null;
		}

		return response;
	}

}
